#include <stdio.h>
#include <sys/epoll.h>
#include <pthread.h>
#include <unistd.h>
#include "../include/my_tcp_server.h"
#include "../include/my_msg_thread.h"
#include "../include/my_list.h"


int epid;
int server_sk;
my_list* fdList;

// 使用EPoll模型构建一个服务器
int my_tcp_server_init(pthread_t *pid)
{
    fdList = my_list_init();

    //创建socket
    server_sk = socket(AF_INET, SOCK_STREAM, 0);
    if(server_sk == -1){
        printf("服务端socket创建失败\n");
        return -1;
    }
    //绑定ip地址和端口号
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(TCP_SERVER_IP);
    addr.sin_port = htons(TCP_SERVER_PORT);
    if(bind(server_sk, (struct sockaddr *)&addr, sizeof(addr)) == -1){
        printf("服务器ip地址和端口绑定(bind)失败\n");
        return -1;
    }
    //listen
    if(listen(server_sk, 50) == -1){
        printf("服务器listen失败\n");
        return -1;
    }
    //添加epoll模型
    epid = epoll_create1(0);
    if(epid == -1){
        printf("epoll_create1失败\n");
        return -1;
    }
    //epoll_ctl add
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = server_sk;
    if(epoll_ctl(epid, EPOLL_CTL_ADD, server_sk, &event) == -1){
        printf("epoll_ctl失败\n");
        return -1;
    }
    //while(1)
    if(pthread_create(pid, NULL, server_thread_run, NULL)!=0){
        printf("服务器线程创建失败\n");
        return -1;
    }

    return 0;
}


void* server_thread_run(void* arg){
    while(1){
        struct epoll_event events[10];
        int nums=epoll_wait(epid, events, 10, -1);
        for(int i=0;i<nums;i++){
            int fd = events[i].data.fd;
            printf("epoll_wait事件轮询 fd=[%d]\n", fd);
            if(fd == server_sk){
                int client_fd = accept(server_sk, NULL, NULL);
                struct epoll_event event;
                event.events = EPOLLIN;
                event.data.fd = client_fd;
                epoll_ctl(epid, EPOLL_CTL_ADD, client_fd, &event);
                //还要维护一个全局数组，存储clientid，以便下发
                my_list_add(fdList, client_fd);
                printf("有新的tcp客户端连接, client_fd=[%d], fdList.len=[%d]\n", client_fd, fdList->len);
                continue;
            }
            //tcp通信
            printf("收到来自client_fd=[%d]的报文\n", fd);
            int mtype;
            ssize_t cnt = recv(fd, &mtype, 4, MSG_WAITALL);
            printf("111 tcp_read.cnt=[%ld]\n", cnt);
            if(cnt == 0){//tcp连接断开了
                printf("断开tcp连接 fd=[%d]\n", fd);
                close(fd);
                my_list_remove(fdList, fd);
                continue;
            }
            printf("收到TCP消息 mytype=[%d]\n", mtype);
            //
            int len;
            cnt = recv(fd, &len, 4, MSG_WAITALL);
            printf("222 tcp_read.cnt=[%ld]\n", cnt);
            //目前只有一种报文类型，故不做判断
            unsigned int buf[1000];
            
            cnt = recv(fd, (void*)buf, sizeof(buf), MSG_WAITALL);
            printf("333 tcp_read.cnt=[%ld]\n", cnt);
            if(cnt == 0){//tcp连接断开了
                printf("断开tcp连接 fd=[%d]\n", fd);
                close(fd);
                my_list_remove(fdList, fd);
                continue;
            }
            //通过消息队列上送到边缘计算程序
            my_msg_thread_send(buf, 1000);
        }
    }
}

int my_tcp_server_sendTakeWave(){
    //单链表的遍历
    my_node* p = fdList->next;
    int i=0;
    while(p){
        //发数据
        printf("111 i=[%d]\n", i);
        char buf[8]={0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        ssize_t cnt = write(p->fd, buf, sizeof(buf));
        printf("333 i=[%d], write_cnt=[%ld]\n", i, cnt);

        //
        p = p->next;
        i++;
    }


}